﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;

namespace SignDetection
{
    public struct Geometry
    {
        public double b;
        public double g;
        public double r;
    }
    public class ColorClasiffier
    {
        Bitmap ori_bitmap;
        Bitmap RGB_bitmap;

        int R = 255;
        int G = 255;
        int B = 255;
        int XLENGTH;// =;// YLENGTH*Math.Cos(Math.PI/3);
        int YLENGTH;//=(int)(256*Math.Sqrt(2));
        public Bitmap Classify(Bitmap srcbitmap)
        {
            Bitmap result = new Bitmap(srcbitmap.Width, srcbitmap.Height);
            return result;
        }
        public static Bitmap Histo(Bitmap cls_bitmap, int XLENGTH, int YLENGTH)
        {
            Bitmap bitmap = new Bitmap(XLENGTH, YLENGTH);
            //Bitmap bitmap = new Bitmap(XLENGTH, YLENGTH);

            int[,] Hist = new int[XLENGTH, YLENGTH];
            int[] Gray_Hist = new int[256];
            for (int i = 0; i < cls_bitmap.Width; i++)
                for (int j = 0; j < cls_bitmap.Height; j++)
                {
                    Color pixel = cls_bitmap.GetPixel(i, j);
                    Point family = ColorMap.MapColor(pixel);
                    int gray = (int)((pixel.R + pixel.G + pixel.B) / 3);
                    Gray_Hist[gray]++;
                    int x = family.X;
                    int y = family.Y;
                    if (y < YLENGTH && x < XLENGTH && y >= 0 && x >= 0)
                        Hist[x, y]++;
                    else
                    {
                        if (x < -5 || (x - XLENGTH) > 5
                        || y < -5 || (y - YLENGTH) > 5)
                            throw new Exception("Impossible!");
                        continue;
                    }
                }
            //找最大值最小值
            int max = Hist[0, 0];
            int min = Hist[0, 0];
            for (int x = 0; x < XLENGTH; x++)
                for (int y = 0; y < YLENGTH; y++)
                {
                    int his = Hist[x, y];
                    if (max < his)
                        max = his;
                    if (min > his)
                        min = his;
                }

            for (int x = 0; x < XLENGTH; x++)
                for (int y = 0; y < YLENGTH; y++)
                {
                    int Pixel = 0;
                    if (Hist[x, y] > 0)
                        Pixel = (int)(255 * Math.Log10(Hist[x, y]) / (Math.Log10(max)));
                  
                    bitmap.SetPixel(x, y, Color.FromArgb(Pixel, Pixel, Pixel));
                }

            Point orginal = new Point((int)ColorMap.offsetx, (int)ColorMap.offsety);
            Graphics g = Graphics.FromImage(bitmap);
            g.DrawEllipse(new Pen(Color.White), 0, 0, 3, 3);
            Point blue = ColorMap.MapColor(Color.FromArgb(0, 0, 255));
            Point green = ColorMap.MapColor(Color.FromArgb(0, 255, 0));
            Point red = ColorMap.MapColor(Color.FromArgb(255, 0, 0));
            g.DrawLine(new Pen(Color.Blue), orginal, blue);
            g.DrawLine(new Pen(Color.Green), orginal, green);
            g.DrawLine(new Pen(Color.Red), orginal, red);
            return bitmap;
        }
    public Bitmap ColorPlane()
    {
           YLENGTH = (int)(256 * Math.Sqrt(2));
             XLENGTH = (int)(YLENGTH * Math.Sin(Math.PI / 3));
           RGB_bitmap = new Bitmap(500, 20);
            ori_bitmap = new Bitmap(256, 256);
            
            R = 255;
            Geometry point_E;
            for (B = 0; B < 256; B++)
                for (G = 0; G < 256; G++)
                {
                    point_E.b = 255 * B / (double)(R + G + B);
                    point_E.g = 255 * G / (double)(R + G + B);
                    point_E.r = 255 * R / (double)(R + G + B);
                    ori_bitmap.SetPixel((int)point_E.b, (int)point_E.g, Color.FromArgb(R, G, B));
                }
            G = 255;
            for (R = 0; R < 256; R++)
                for (B = 0; B < 256; B++)
                {
                    point_E.b = 255 * B / (double)(R + G + B);
                    point_E.g = 255 * G / (double)(R + G + B);
                    point_E.r = 255 * R / (double)(R + G + B);
                    ori_bitmap.SetPixel((int)point_E.b, (int)point_E.g, Color.FromArgb(R, G, B));
                }
            B = 255;
            for (R = 0; R < 256; R++)
                for (G = 0; G < 256; G++)
                {
                    point_E.b = 255 * B / (double)(R + G + B);
                    point_E.g = 255 * G / (double)(R + G + B);
                    point_E.r = 255 * R / (double)(R + G + B);
                    ori_bitmap.SetPixel((int)point_E.b, (int)point_E.g, Color.FromArgb(R, G, B));
                }
           return ori_bitmap;
    }
   
    }
    //public class ColorMap
    //{
    //    static Geometry point_A;
    //    static Geometry point_S;//色系平面原点
    //    static bool initialized = false;
    //    public static double offsetx;
    //    public static double offsety;
    //    static void Initialize()
    //    {
    //        if (initialized)
    //            return;
    //        point_A.b = 255;
    //        point_A.g = 0;
    //        point_A.r = 0;

    //        point_S.b = 85;
    //        point_S.g = 85;
    //        point_S.r = 85;
    //        offsety = (255 * Math.Sqrt(2.0)) / 2;
    //        offsetx = offsety * Math.Tan(Math.PI / 6) + 2;
    //    }
    //    static void Polarize(Geometry point_S, Geometry point_A, Geometry point_E, ref double angle, ref double seLength)
    //    {
    //        double sex = point_E.b - point_S.b;
    //        double sey = point_E.g - point_S.g;
    //        double sez = point_E.r - point_S.r;
    //        double sax = point_A.b - point_S.b;
    //        double say = point_A.g - point_S.g;
    //        double saz = point_A.r - point_S.r;

    //        seLength = Math.Sqrt(sex * sex + sey * sey + sez * sez);
    //        double saLength = Math.Sqrt(sax * sax + say * say + saz * saz);
    //        if (seLength != 0)
    //        {
    //            double saMse = sex * sax + sey * say + sez * saz;
    //            if (saMse / (seLength * saLength) <= 1 && saMse / (seLength * saLength) >= -1)
    //            {
    //                angle = Math.Acos(saMse / (seLength * saLength));
    //                if (point_E.g < point_E.r)
    //                    angle = -angle;
    //            }
    //        }
    //    }

    //    public static Point MapColor(Color pixel)
    //    {
    //        Initialize();
    //        Geometry point_E;//色系射线与色系平面的交点
    //        point_E.b = 255 * pixel.B / (double)(pixel.R + pixel.G + pixel.B);
    //        point_E.g = 255 * pixel.G / (double)(pixel.R + pixel.G + pixel.B);
    //        point_E.r = 255 * pixel.R / (double)(pixel.R + pixel.G + pixel.B);
    //        double angle = 0;
    //        double seLength = 0;
    //        Polarize(point_S, point_A, point_E, ref angle, ref seLength);
    //        Point point = new Point();
    //        point.X = (int)(offsetx + (seLength * Math.Cos(angle)));
    //        point.Y = (int)(offsety + (int)(seLength * Math.Sin(angle)));
    //        return point;
    //    }
    //}
}
